import Vue from 'vue';
import {on,hasClass} from './dom';

const nodeList = [];
const ctx = '@@clickoutsideContext';

!Vue.prototype.$isServer && on(document, 'click', e => {
    nodeList.forEach(node => {
        var argument = node[ctx].argument;
        if(hasClass(e.target,argument))
            return;
        node[ctx].documentHandler(e)
    });
});

/**
 * v-clickoutside
 * @desc 点击元素外面才会触发的事件
 * @example
 * ```vue
 * <div v-element-clickoutside="handleClose">
 * ```
 */
export default {
    bind(el, binding, vnode) {
        const id = nodeList.push(el) - 1;

        const documentHandler = function (e) {
            if (!vnode.context ||
                el.contains(e.target) ||
                (vnode.context.popperElm &&
                vnode.context.popperElm.contains(e.target))) return;

            if (binding.expression &&
                el[ctx].methodName &&
                vnode.context[el[ctx].methodName]) {
                vnode.context[el[ctx].methodName]();
            } else {
                el[ctx].bindingFn && el[ctx].bindingFn();
            }
        };
        el[ctx] = {
            id,
            documentHandler,
            methodName: binding.expression,
            bindingFn: binding.value,
            argument: binding.arg
        };
    },

    update(el, binding) {
        el[ctx].methodName = binding.expression;
        el[ctx].bindingFn = binding.value;
    },

    unbind(el) {
        let len = nodeList.length;

        for (let i = 0; i < len; i++) {
            if (nodeList[i][ctx].id === el[ctx].id) {
                nodeList.splice(i, 1);
                break;
            }
        }
    }
};
